// Core.cpp
#include "Core.h"
#include <QDebug>
#include "util/Logger.h"

Core::Core() { Logger::getInstance().init(); }

Core::~Core()
{
    QMutexLocker locker(&m_mutex);

    for (auto plugin : m_uiPlugins) {
        plugin->shutdown();
        // 不delete接口指针，插件由QPluginLoader管理
    }
    for (auto plugin : m_functionPlugins) {
        plugin->shutdown();
        // 不delete接口指针
    }

    // 卸载插件
    for (auto& loader : m_pluginLoaders) {
        loader->unload();
    }
    m_pluginLoaders.clear();

    m_uiPlugins.clear();
    m_functionPlugins.clear();
}

bool Core::loadPluginsFromRootDirectory(const QString& rootDir)
{
    QString uiDir = rootDir + "/uiplugins";
    QString funcDir = rootDir + "/functionplugins";

    bool uiLoaded = loadUIPluginsFromDirectory(uiDir);
    bool funcLoaded = loadFunctionPluginsFromDirectory(funcDir);

    return uiLoaded && funcLoaded;
}

bool Core::loadUIPluginsFromDirectory(const QString& dirPath)
{
    QDir dir(dirPath);
    if (!dir.exists()) {
        logMessage("Core", QString("UI插件目录不存在: %1").arg(dirPath));
        return false;
    }

    bool anyLoaded = false;

    for (const auto& fileName : dir.entryList(QDir::Files)) {
        QString filePath = dir.absoluteFilePath(fileName);
        auto loader = std::make_unique<QPluginLoader>(filePath);
        QObject* instance = loader->instance();
        if (!instance) {
            logMessage(
                "Core",
                QString("加载UI插件失败: %1，错误: %2").arg(fileName, loader->errorString()));
            continue;
        }

        if (auto uiPlugin = qobject_cast<IUIPlugin*>(instance)) {
            QString id = uiPlugin->pluginInfo().id;

            QMutexLocker locker(&m_mutex);
            if (m_uiPlugins.contains(id)) {
                logMessage("Core", QString("UI插件重复ID: %1，忽略加载").arg(id));
                loader->unload();
                continue;
            }

            if (!uiPlugin->initialize(this)) {
                logMessage("Core", QString("UI插件初始化失败: %1，忽略加载").arg(id));
                loader->unload();
                continue;
            }

            m_uiPlugins[id] = uiPlugin;
            m_pluginLoaders[id] = std::move(loader);
            logMessage("Core", QString("加载UI插件: %1").arg(id));
            anyLoaded = true;
        } else {
            logMessage("Core", QString("非UI插件，忽略: %1").arg(fileName));
            loader->unload();
        }
    }
    return anyLoaded;
}

bool Core::loadFunctionPluginsFromDirectory(const QString& dirPath)
{
    QDir dir(dirPath);
    if (!dir.exists()) {
        logMessage("Core", QString("功能插件目录不存在: %1").arg(dirPath));
        return false;
    }

    bool anyLoaded = false;

    for (const auto& fileName : dir.entryList(QDir::Files)) {
        QString filePath = dir.absoluteFilePath(fileName);
        auto loader = std::make_unique<QPluginLoader>(filePath);
        QObject* instance = loader->instance();
        if (!instance) {
            logMessage(
                "Core",
                QString("加载功能插件失败: %1，错误: %2").arg(fileName, loader->errorString()));
            continue;
        }

        if (auto funcPlugin = qobject_cast<IFunctionPlugin*>(instance)) {
            QString id = funcPlugin->pluginInfo().id;

            QMutexLocker locker(&m_mutex);
            if (m_functionPlugins.contains(id)) {
                logMessage("Core", QString("功能插件重复ID: %1，忽略加载").arg(id));
                loader->unload();
                continue;
            }

            if (!funcPlugin->initialize(this)) {
                logMessage("Core", QString("功能插件初始化失败: %1，忽略加载").arg(id));
                loader->unload();
                continue;
            }

            m_functionPlugins[id] = funcPlugin;
            m_pluginLoaders[id] = std::move(loader);
            logMessage("Core", QString("加载功能插件: %1").arg(id));
            anyLoaded = true;
        } else {
            logMessage("Core", QString("非功能插件，忽略: %1").arg(fileName));
            loader->unload();
        }
    }
    return anyLoaded;
}

IUIPlugin* Core::getUIPlugin(const QString& pluginId) const
{
    QMutexLocker locker(&m_mutex);
    return m_uiPlugins.value(pluginId, nullptr);
}

IFunctionPlugin* Core::getFunctionPlugin(const QString& pluginId) const
{
    QMutexLocker locker(&m_mutex);
    return m_functionPlugins.value(pluginId, nullptr);
}

QStringList Core::listUIPluginIds() const
{
    QMutexLocker locker(&m_mutex);
    return m_uiPlugins.keys();
}

QStringList Core::listFunctionPluginIds() const
{
    QMutexLocker locker(&m_mutex);
    return m_functionPlugins.keys();
}

void Core::subscribeEvent(const QString& eventName, std::function<void(const PluginInfo&)> callback)
{
    QMutexLocker locker(&m_mutex);
    m_eventSubscribers.insert(eventName, callback);
}

void Core::publishEvent(const PluginInfo& event)
{
    QMutexLocker locker(&m_mutex);
    auto range = m_eventSubscribers.equal_range(event.eventName);
    for (auto it = range.first; it != range.second; ++it) {
        try {
            it.value()(event);
        } catch (...) {
            logMessage("Core", "事件回调异常");
        }
    }
}

void Core::logMessage(const QString& pluginId, const QString& message)
{
    CDEBUG() << " id : " << pluginId << ", message : " << message;
}
